package com.stox.client.ui.javafx.watchlist.widget;

import java.util.ArrayList;
import java.util.List;

import javafx.beans.binding.ListBinding;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.util.Callback;

import com.stox.client.api.core.Client;
import com.stox.client.ui.javafx.core.util.CSS;
import com.stox.client.ui.javafx.core.util.UI;
import com.stox.client.ui.javafx.watchlist.model.OWatchlist;
import com.stox.client.ui.javafx.widget.AbstractHasScripTableView;
import com.stox.shared.core.i18n.MessageSource;
import com.stox.shared.watchlist.model.WatchlistEntry;

public class WatchlistEntryTableView extends AbstractHasScripTableView<WatchlistEntry> {

	private final WatchlistComboBox watchlistComboBox;
	private final EventHandler<ActionEvent> deleteEventHandler = new EventHandler<ActionEvent>(){
		public void handle(ActionEvent event) {
			Button button = (Button)event.getSource();
			WatchlistEntry watchlistEntry = (WatchlistEntry)button.getUserData();
			deleteWatchlistEntry(watchlistEntry);
		}
	};
	
	public WatchlistEntryTableView(WatchlistComboBox watchlistComboBox) {
		super(WatchlistEntry.class);
		this.watchlistComboBox = watchlistComboBox;
		itemsProperty().bind(new ListBinding<WatchlistEntry>(){
			
			{super.bind(watchlistComboBox.valueProperty());}
			
			@Override
			protected ObservableList<WatchlistEntry> computeValue() {
				OWatchlist watchlist = watchlistComboBox.getValue();
				if(null != watchlist){
					if(null == watchlist.getEntries() || watchlist.getEntries().isEmpty()){
						final List<WatchlistEntry> watchlistEntries = Client.WATCHLIST_ENTRY.findByWatchlistId(watchlist.getId());
						watchlist.getEntries().setAll(watchlistEntries);
					}
					return watchlist.getEntries();
				}
				return null;
			}
		});
		
		if(!watchlistComboBox.getItems().isEmpty()){
			watchlistComboBox.getSelectionModel().select(0);
		}
				
		TableColumn<WatchlistEntry, Button> deleteColumn = new TableColumn<>();
		Button deleteAllButton = UI.mediumCrossButton(MessageSource.get("DeleteAll"));
		deleteAllButton.setOnAction(new EventHandler<ActionEvent>(){
			@Override
			public void handle(ActionEvent event) {
				// getItems method can not be used directly, as it gives ConcurrentModificaitonException
				List<WatchlistEntry> watchlistEntries = new ArrayList<>(getItems());
				for(WatchlistEntry watchlistEntry : watchlistEntries){
					deleteWatchlistEntry(watchlistEntry);
				}
			}
		});
		deleteColumn.setGraphic(deleteAllButton);
		UI.style(deleteColumn, CSS.watchlistColumnDelete);
		deleteColumn.setMaxWidth(30);
		deleteColumn.setMinWidth(30);
		deleteColumn.setPrefWidth(30);
		deleteColumn.setCellFactory(new Callback<TableColumn<WatchlistEntry,Button>, TableCell<WatchlistEntry,Button>>() {
			@Override
			public TableCell<WatchlistEntry, Button> call(
					TableColumn<WatchlistEntry, Button> button) {
				return new TableCell<WatchlistEntry, Button>(){
					@Override
					protected void updateItem(Button item, boolean empty) {
						super.updateItem(item, empty);
						setAlignment(Pos.CENTER);
						setCenterShape(true);
						setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
						if(!empty){
							setGraphic(item);
						}else{
							setGraphic(null);
						}
					}
				};
			}
		});
		deleteColumn.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<WatchlistEntry,Button>, ObservableValue<Button>>() {
			@Override
			public ObservableValue<Button> call(
					CellDataFeatures<WatchlistEntry, Button> param) {
				Button button = UI.mediumCrossButton(MessageSource.get("Delete"));
				button.setOnAction(deleteEventHandler);
				button.setUserData(param.getValue());
				return new ReadOnlyObjectWrapper<>(button);
			}
		});
		getColumns().add(deleteColumn);
	}
	
	public void addWatchlistEntry(WatchlistEntry watchlistEntry){
		
		if(null != watchlistEntry 
				&& null != watchlistEntry.getWatchlistId() 
				&& 0 != watchlistEntry.getWatchlistId() 
				&& null != watchlistEntry.getScripId() 
				&& 0 != watchlistEntry.getScripId() 
				&& null != watchlistComboBox){
			
			OWatchlist watchlist = OWatchlist.getWatchlistById(watchlistEntry.getWatchlistId());
			if(null != watchlist){
				watchlist.getEntries().add(watchlistEntry);
			}
		}
			
	}
	
	public void deleteWatchlistEntry(WatchlistEntry watchlistEntry){
		Client.WATCHLIST_ENTRY.delete(watchlistEntry.getId());
		OWatchlist watchlist = OWatchlist.getWatchlistById(watchlistEntry.getWatchlistId());
		if(null != watchlist){
			watchlist.getEntries().remove(watchlistEntry);
		}
	}
	
	
}